随笔分类
join
无限等待
等待线程的完成
Waiting for the finalization of a thread
In some situations, we will have to wait for the finalization of a thread. For example, we may have a program that will begin initializing the resources it needs before proceeding with the rest of the execution. We can run the initialization tasks as threads and wait for its finalization before continuing with the rest of the program. For this purpose, we can use the join() method of the Thread class. When we call this method using a thread object, it suspends the execution of the calling thread until the object called finishes its execution.
在某些情况下,我们必须等待线程的完成.例如,我们可能有一个程序,它将开始初始化它所需的资源,然后继续执行其余部分.我们可以以线程状态运行初始化任务,并等待其完成,然后继续执行程序的其余部分,为此我们可以使用Thread类的join()方法.当我们使用线程对象调用此方法时,它将挂起调用线程的执行,直到被调用的对象完成其执行
当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行
线程A对线程B调用了join(),表明只有在线程B进入终止状态后,线程A才能够继续往下执行
/**
* Waits for this thread to die. //等待调用该方法的线程死亡,当前线程才继续执行
*
* <p> An invocation of this method behaves in exactly the same
* way as the invocation
*
* <blockquote>
* {@linkplain #join(long) join}{@code (0)}
* </blockquote>
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final void join() throws InterruptedException {
join(0);//调用join()之后,会去调用join(0)
}
/**
* ....
* ....
* 992
* 993
* 994
* 995
* 996
* 997
* 998
* 999
* All Thread is over
*/
public class ThreadTest {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i =0; i < 1000; i++){
System.out.println(i);
}
System.out.println(Thread.currentThread().getName());//Thread-0
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());//main
System.out.println("All Thread is over");
}
}
解读
/**
* Waits for this thread to die.
* 等待调用该方法的线程死亡,当前线程才继续执行,再次期间阻塞
*
* <p> An invocation of this method behaves in exactly the same
* way as the invocation
*
* <blockquote>
* {@linkplain #join(long) join}{@code (0)}
* </blockquote>
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
* 如果有其它线程中断了当前线程.引发此异常时,会清除当前线程的中断状态(良夜注:是指当前线程不对中断进行处理)
*/
public final void join() throws InterruptedException {
join(0);//传递的参数为0
}
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
* 此实现使用的循环this.isAlive 调用this.wait(良夜注:wait是Object中的本地方法,让当前线程释放其拥有的所有锁,进入等待阻塞队列,等待被唤醒重新获得锁以便以及执行程序) 当线程终止时,将调用this.notifyAll方法。 建议应用程序不要在Thread实例上使用wait , notify或notifyAll
* @param millis
* the time to wait in milliseconds
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
* //millis如果为负,将会抛 IllegalArgumentException
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final synchronized void join(long millis) //注意了,这个方法是个同步方法,也就意味着调用线程会获得线程对象的一把锁,其它线程也就不能去访问该线程对象的该方法了
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {//判断调用该方法的线程是否还活着
wait(0);//主线程释放其拥有的所有锁,放弃cpu,进入无限等待队列,等待唤醒(良夜注:等待线程对象调用this.notifyAll())
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
当线程对象的状态不为Active(状态是TERMINATED)时,会去调用notifyAll(),此时调用线程会被唤醒,当其获取CPU和锁之后,将继续往下执行程序的其余部分
需要注意的是,在调用线程进入线程对象join(0)期间,别的线程能进去线程对象的join(),但是进不去线程对象的join(0),因为它是个同步方法